//
//  YHIMUIKit.m
//  YHChat
//
//  Created by apple on 2019/2/18.
//  Copyright © 2019 yinhe. All rights reserved.
//

#import "YHIMUIKit.h"
#import <pthread/pthread.h>
#import <ImSDK/ImSDK.h>

#import "YHIMUIKitDefine.h"
#import "YHIMUIKitConvCellData.h"

#define YHIMUIKitLock     pthread_mutex_lock(&self->_lock);
#define YHIMUIKitUnLock   pthread_mutex_unlock(&self->_lock);

NSString *const kYHIMUIKitConversationDidChangeNotification = @"kYHIMUIKitConversationDidChangeNotification";

@interface YHIMUIKit ()
<TIMConnListener,
TIMUserStatusListener,
TIMRefreshListener,
TIMMessageRevokeListener,
TIMUploadProgressListener,
TIMMessageListener,
TIMMessageReceiptListener,
TIMMessageUpdateListener,
TIMGroupEventListener>
{
    pthread_mutex_t _lock;
}

@property (nonatomic, strong) NSMutableArray<YHIMUIKitConvCellData *> *allConversationList;
@property (nonatomic, assign) int allUnReadMsgCount;

@end


@implementation YHIMUIKit


+ (instancetype)sharedInstance{
    static YHIMUIKit *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        pthread_mutex_init(&_lock, NULL);
        self.allConversationList = [NSMutableArray array];
        self.allUnReadMsgCount = 0;
    }
    return self;
}


- (void)initSDKWithAppID:(NSString *)appID accountType:(NSString *)accountType{
    TIMManager *manager = [TIMManager sharedInstance];
    
    TIMSdkConfig *sdkConfig = [[TIMSdkConfig alloc] init];
    sdkConfig.sdkAppId = [appID intValue];
    sdkConfig.accountType = accountType;
    //sdkConfig.disableCrashReport = YES;//禁用crash上报
    sdkConfig.disableLogPrint = YES;//禁止在控制台打印log
    sdkConfig.logLevel = TIM_LOG_NONE;//日志等级
    sdkConfig.connListener = self; // <TIMConnListener>
    [manager initSdk:sdkConfig];
    
    TIMUserConfig *userConfig = [[TIMUserConfig alloc] init];
    //userConfig.disableStorage = NO; // 不禁用本地存储
    userConfig.enableReadReceipt = YES; // 开启已读回执
    //userConfig.disableRecnetContact = NO; // 开启最近联系人
    //userConfig.disableRecentContactNotify = YES; // 不通过onNewMessage:抛出最新联系人的最后一条消息
    
    userConfig.userStatusListener = self; // <TIMUserStatusListener>
    userConfig.refreshListener = self; // <TIMRefreshListener>
    userConfig.messageRevokeListener = self; // <TIMMessageRevokeListener>
    userConfig.uploadProgressListener = self; // <TIMUploadProgressListener>
    
    userConfig.messageReceiptListener = self; // <TIMMessageReceiptListener>
    userConfig.messageUpdateListener = self; // <TIMMessageUpdateListener>
    userConfig.groupEventListener = self; // <TIMGroupEventListener>
    
    [manager setUserConfig:userConfig];
    
}

- (void)loginWithIdentifier:(NSString *)identifier userSign:(NSString *)userSign completionBlock:(void (^)(NSError * _Nullable))completionBlock{
    TIMLoginParam *loginParam = [[TIMLoginParam alloc] init];
    loginParam.appidAt3rd = identifier;
    loginParam.userSig = userSign;
    loginParam.identifier = identifier;
    [[TIMManager sharedInstance] login:loginParam succ:^{
        [[TIMManager sharedInstance] addMessageListener:[YHIMUIKit sharedInstance]];
        completionBlock ? completionBlock(nil) : nil;
    } fail:^(int code, NSString *msg) {
        NSError *error = YHIMUIKitError(msg, code);
        completionBlock ? completionBlock(error) : nil;
    }];
}


- (void)logoutWithCompletionBlock:(void (^)(NSError * _Nullable))completionBlock{
    [[TIMManager sharedInstance] logout:^{
        [[TIMManager sharedInstance] removeMessageListener:[YHIMUIKit sharedInstance]];
        completionBlock ? completionBlock(nil) : nil;
    } fail:^(int code, NSString *msg) {
        NSError *error = YHIMUIKitError(msg, code);
        completionBlock ? completionBlock(error) : nil;
    }];
}


#pragma mark -
// 获取所有会话列表
- (void)loadAllConversationList{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        YHIMUIKitLock;
        [self.allConversationList removeAllObjects];
        NSArray<TIMConversation *> *originConversationList = [[TIMManager sharedInstance] getConversationList];
        [originConversationList enumerateObjectsUsingBlock:^(TIMConversation * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            //if ([obj getType] != TIM_SYSTEM) {
                YHIMUIKitConvCellData *cellData = [[YHIMUIKitConvCellData alloc] initWithConv:obj];
                [self.allConversationList addObject:cellData];
            //}
        }];
        // Get all unread message count.
        [self getAllUnReadMsgCount];
        
        // Sned notification.
        [[NSNotificationCenter defaultCenter] postNotificationName:kYHIMUIKitConversationDidChangeNotification object:nil];
        
        YHIMUIKitUnLock;
    });
}

// 获取所有消息的未读计数
- (void)getAllUnReadMsgCount{
    __block int count = 0;
    [self.allConversationList enumerateObjectsUsingBlock:^(YHIMUIKitConvCellData * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (obj.convType != YHIMUIKitConvType_System) {
            count += obj.unReadCount;
        }
    }];
    self.allUnReadMsgCount = count;
}



#pragma mark - <TIMConnListener>  网络监听器
- (void)onConnSucc{
    YHIMUIKitLog(@"<TIMConnListener> 网络连接成功");
}

- (void)onConnFailed:(int)code err:(NSString *)err{
    YHIMUIKitLog(@"<TIMConnListener> 网络连接失败,[CODE]:%d, [MSG]:%@", code, err);
}

- (void)onDisconnect:(int)code err:(NSString *)err{
    //断线只是通知用户，不需要重新登陆，重连以后会自动上线
    YHIMUIKitLog(@"<TIMConnListener> 网络连接断开, [CODE]:%d, [MSG]:%@", code, err);
}

- (void)onConnecting{
    YHIMUIKitLog(@"<TIMConnListener> 网络连接中...");
}

#pragma mark - <TIMUserStatusListener>  用户登录状态监听器
- (void)onForceOffline{
    YHIMUIKitLog(@"<TIMUserStatusListener> 被踢下线");//收到此回调可以令APP退出登录，并给用户一个明确的提示。
}

- (void)onReConnFailed:(int)code err:(NSString *)err{
    YHIMUIKitLog(@"<TIMUserStatusListener> 断线重连失败, [CODE]:%d, [MSG]:%@", code, err);
}

- (void)onUserSigExpired{
    YHIMUIKitLog(@"<TIMUserStatusListener> 登录失效，需要重新获取userSig后登录");//收到此回调可以令APP退出登录，并给用户一个明确的提示。
}

#pragma mark - <TIMMessageListener>  消息回调
- (void)onNewMessage:(NSArray *)msgs{
    YHIMUIKitLog(@"<TIMMessageListener> 新消息回调通知");
    [self loadAllConversationList];
}

#pragma mark - <TIMRefreshListener>  会话刷新监听器（未读计数、已读同步）（加载消息扩展包有效）
- (void)onRefresh{
    YHIMUIKitLog(@"<TIMRefreshListener> 刷新会话");
    [self loadAllConversationList];
}

- (void)onRefreshConversations:(NSArray *)conversations{
    YHIMUIKitLog(@"<TIMRefreshListener> 刷新部分会话（包括多终端已读上报同步）");
    [self loadAllConversationList];
}

#pragma mark - <TIMMessageRevokeListener>  消息撤回监听器（加载消息扩展包有效）
- (void)onRevokeMessage:(TIMMessageLocator *)locator{
    YHIMUIKitLog(@"<TIMMessageRevokeListener> 消息撤回通知");
}

#pragma mark - <TIMUploadProgressListener>  文件上传进度监听器
- (void)onUploadProgressCallback:(TIMMessage *)msg elemidx:(uint32_t)elemidx taskid:(uint32_t)taskid progress:(uint32_t)progress{
    YHIMUIKitLog(@"<TIMUploadProgressListener> 上传进度回调  %d", progress);
}

#pragma mark - <TIMMessageReceiptListener>  消息已读回执监听器（加载消息扩展包有效）
- (void)onRecvMessageReceipts:(NSArray *)receipts{
    YHIMUIKitLog(@"<TIMMessageReceiptListener> 收到了已读回执");
}

#pragma mark - <TIMMessageUpdateListener>  消息svr重写监听器（加载消息扩展包有效）
- (void)onMessageUpdate:(NSArray *)msgs{
    YHIMUIKitLog(@"<TIMMessageUpdateListener> 消息修改通知");
}

#pragma mark - <TIMGroupListener>  群组据本地缓存监听器（加载群组扩展包、enableGroupAssistant有效）
- (void)onMemberJoin:(NSString*)groupId membersInfo:(NSArray*)membersInfo{
    YHIMUIKitLog(@"<TIMGroupListener> 有新用户加入群时的通知回调  groupId:%@   membersInfo:%@", groupId, membersInfo);
}

- (void)onMemberQuit:(NSString*)groupId members:(NSArray*)members{
    YHIMUIKitLog(@"<TIMGroupListener> 有群成员退群时的通知回调  groupId:%@  members:%@", groupId, members);
}


- (void)onMemberUpdate:(NSString*)groupId membersInfo:(NSArray*)membersInfo{
    YHIMUIKitLog(@"<TIMGroupListener> 群成员信息更新的通知回调  groupId:%@   membersInfo:%@", groupId, membersInfo);
}


- (void)onGroupAdd:(TIMGroupInfo*)groupInfo{
    YHIMUIKitLog(@"<TIMGroupListener> 加入群的通知回调  groupInfo:%@", groupInfo);
}


- (void)onGroupDelete:(NSString*)groupId{
    YHIMUIKitLog(@"<TIMGroupListener> 本地群组资料被删除的通知回调，包括主动退群，被踢，群被解散，群被回收  groupId:%@", groupId);
}


- (void)onGroupUpdate:(TIMGroupInfo*)groupInfo{
    YHIMUIKitLog(@"<TIMGroupListener> 群资料更新的通知回调  groupInfo:%@", groupInfo);
}
@end
